﻿#region using statements

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

#endregion

namespace XNAGameEngine.Particles
{
    /// <summary>
    /// A particle for a particle system.
    /// </summary>
    public class Particle
    {
        #region local fields

        /// <summary>
        /// The origin 
        /// </summary>
        public Vector2 _origin;

        /// <summary>
        /// The source rectangle of the image used for the particle
        /// </summary>
        public Rectangle _sourceRectangle;

        /// <summary>
        /// The image used for the particle
        /// </summary>
        public Texture2D _texture;

        /// <summary>
        /// The position of the particle
        /// </summary>
        public Vector2 _position;

        /// <summary>
        /// The velocity of the particle
        /// </summary>
        public Vector2 _posVelocity;

        /// <summary>
        /// The acceleration of the particle
        /// </summary>
        public Vector2 _posAcceleration;

        /// <summary>
        /// The color overlay of the particle
        /// </summary>
        public Color _color;

        /// <summary>
        /// The rotation value of the particle
        /// </summary>
        public double _angle;

        /// <summary>
        /// The rotational velocity of the particle (how fast it spins)
        /// </summary>
        public double _angVelocity;

        /// <summary>
        /// The rotational acceleration of the particle
        /// </summary>
        public double _angAcceleration;

        /// <summary>
        /// The scale of the particle
        /// </summary>
        public Vector2 _scale;

        /// <summary>
        /// The scalar velocity of the particle (linear rate of growth)
        /// </summary>
        public Vector2 _scaVelocity;

        /// <summary>
        /// The scalar acceleration of the particle (exponential rate of growth)
        /// </summary>
        public Vector2 _scaAcceleration;

        /// <summary>
        /// The life in seconds of the particle
        /// </summary>
        public double _timeToLive;

        #endregion

        #region constructors

        /// <summary>
        /// Create a new particle with the passed in parameters
        /// </summary>
        /// <param name="texture">the texture</param>
        /// <param name="color">color overlay</param>
        /// <param name="ttl">amount of time to exist (in seconds)</param>
        /// <param name="position">starting position</param>
        /// <param name="posVelocity">positional velocity</param>
        /// <param name="posAcceleration">positional acceleration</param>
        /// <param name="angle">angle of the image (in radians)</param>
        /// <param name="angVelocity">angular velocity (in radians)</param>
        /// <param name="angAcceleration">angular acceleration (in radians)</param>
        /// <param name="scale">scale of the texture</param>
        /// <param name="scaVelocity">scalar velocity of the texture</param>
        /// <param name="scalarAcceleration">scalar acceleration of the texture</param>
        public Particle(
            Texture2D texture, Color color, double ttl, Vector2 position,
            Vector2 posVelocity, Vector2 posAcceleration, double angle,
            double angVelocity, double angAcceleration, Vector2 scale,
            Vector2 scaVelocity, Vector2 scalarAcceleration)
        {
            _texture = texture;
            _color = color;
            _timeToLive = ttl;
            _position = position;
            _posVelocity = posVelocity;
            _posAcceleration = posAcceleration;
            _angle = angle;
            _angVelocity = angVelocity;
            _angAcceleration = angAcceleration;
            _scale = scale;
            _scaVelocity = scaVelocity;
            _scaAcceleration = scalarAcceleration;
            _sourceRectangle = new Rectangle(0, 0, _texture.Width, _texture.Height);
            _origin = _texture != null ? new Vector2(_texture.Width / 2, _texture.Height / 2) : new Vector2();
        }

        #endregion

        #region local methods

        /// <summary>
        /// Update the particle position, angle, scale and lifetime
        /// </summary>
        /// <param name="gameTime">snapshot of timing values</param>
        public void Update(GameTime gameTime)
        {
            _timeToLive -= (double)gameTime.ElapsedGameTime.Milliseconds / 1000;
            _posVelocity += _posAcceleration;
            _position += _posVelocity;
            _angVelocity += _angAcceleration;
            _angle += _angVelocity;
            _scaVelocity += _scaAcceleration;
            _scale += _scaVelocity;

        }

        /// <summary>
        /// Draw the particle to the screen. Assumes SpriteBatch.Begin() has been called
        /// and SpriteBatch.End() will be called afterwards
        /// </summary>
        /// <param name="spriteBatch">the spritebatch to use to render</param>
        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(
                _texture, _position, _sourceRectangle, _color,
                (float)_angle, _origin, _scale, SpriteEffects.None, 0f);
        }

        #endregion
    }
}